﻿/******************************************************************
 *Company: http://www.xiaomutech.com/
 *fileName : qmp3info.cpp --- QMp3Info
 *Auth       : yhni (QQ:393320854)
 *Create    : 2022/9/16
 *Description   :
 *Histroy:
 *<Auth>    <Date>        <Ver>        <Content>
 *         2022/9/16
 *******************************************************************/
#include "qmp3info.h"

#include <QFile>
#include <QTextStream>
#include <QTextCodec>
#include <QDebug>

QMp3Info::QMp3Info(QObject *parent) : QObject(parent)
{

}

/* 目前只支持mp3IDV2解析 */
bool QMp3Info::analyseMusic(const QString &_path, QMusicItem *_item)
{
    TAB_info tab_info;
    qint64 head_size = 0;       //头部大小
    qint64 file_seek = 0;       //文件指针
    quint64 len;

    QFile file(_path);
    if (!file.open(QIODevice::ReadOnly))
    {
        qDebug() << "open error" << _path;
        return false;
    }

    file.read((char*)&tab_info, sizeof(tab_info));
    file_seek = file_seek + 10;

    /* 判断是否为mp3的IDV2格式 */
    if (QString(tab_info.format) != "ID3\u0003" || (int)tab_info.version != 3)
    {
        qDebug() << "mp3 is not ID3V2 error" << QString(tab_info.format) << (int)tab_info.version;
        return false;
    }

    /* 每8位只用前7位，第8位无效恒为0;  */
    head_size = ((tab_info.header_size[0] & 0xff) << 21);
    head_size |= ((tab_info.header_size[1] & 0xff) << 14);
    head_size |= ((tab_info.header_size[2] & 0xff) << 7);
    head_size |= (tab_info.header_size[3] & 0xff);

    HEAD_info head_info;
    quint32 size;
    QString strSinger;
    while(file_seek < head_size)
    {
        /* 读取头部信息 */
        len = file.read((char*)&head_info, sizeof(head_info));
        file_seek = file_seek+len;
        size  = (head_info.Size[0] & 0xff) << 24;
        size |= (head_info.Size[1] & 0xff) << 16;
        size |= (head_info.Size[2] & 0xff) << 8;
        size |= (head_info.Size[3] & 0xff);

        /* 有"TIT2""TPE1""TALB""TXXX" "TRCK""TPOS""TCON""APIC" */
        if(QString(head_info.FrameID) == "TIT2")        //曲名
        {
            QTextStream stream(&file);
            stream.seek(file.pos() + 1);

            /* unicode编码中文是两个字节为一个中文，外加结束为零。*/
            QString all = stream.readLine((int)(size/2-1));
            QTextCodec *codec = QTextCodec::codecForName("GBK");
            QString name = codec->toUnicode(all.toLocal8Bit().data());
            _item->setSong(name);
            file_seek = file_seek + size;
            file.seek(file_seek);
            continue;
        }

        /* 歌手 */
        if (QString(head_info.FrameID) == "TPE1")
        {
            QTextStream stream(&file);
            stream.seek(file.pos() + 1);
            /* unicode编码中文是两个字节为一个中文，外加结束为零。*/
            QString all = stream.readLine((int)(size / 2 - 1));
            QTextCodec *codec = QTextCodec::codecForName("GBK");
            QString author = codec->toUnicode(all.toLocal8Bit().data());
            _item->setSinger(author);
            file_seek = file_seek + size;
            file.seek(file_seek);
            strSinger = author;
            continue;
        }

        /* 专辑 */
        if (QString(head_info.FrameID) == "TALB")
        {
            QTextStream stream(&file);
            stream.seek(file.pos() + 1);
            /* unicode编码中文是两个字节为一个中文，外加结束为零。*/
            QString all = stream.readLine((int)(size / 2 - 1));
            QTextCodec *codec = QTextCodec::codecForName("GBK");
            QString album = codec->toUnicode(all.toLocal8Bit().data());
            _item->setAlbum(album);
            file_seek = file_seek + size;
            file.seek(file_seek);
            continue;
        }

        /* 图片 */
        if (QString(head_info.FrameID) == "APIC")
        {
            /* 去掉14位为照片描述 */
            file_seek = file_seek + 14;
            file.seek(file_seek);

            char *piture = (char *)malloc(size);
            file.read((char *)piture,size - 14);
            file_seek = file_seek + size - 14;

            /* 判断照片的存储格式jpg/png */
            QString _pixType = "jpg";
            if(((uchar)piture[0] == 137) && ((uchar)piture[1] == 80))
            {
                _pixType = "png";
            }

            QString path = QString("./%1.%2").arg(strSinger).arg(_pixType);
            QFile testpic(path);
            testpic.open(QIODevice::WriteOnly);
            testpic.write(piture, size - 14);
            testpic.close();
            qDebug() << "write" << path << (size - 14);
            free(piture);
            continue;
        }

        //其他信息不需要
        file_seek = file_seek + size;
        file.seek(file_seek);
    }

    file.close();
    return true;
}
